fix(compiler): allow re-assigning inferred local object to another class - #95
fix(compiler): allow re-assigning inferred local object to another class#95Tinywan wants to merge 1 commit into
Conversation
A local variable has no type declaration; its class is inferred from the first assignment. Re-assigning an unrelated concrete class in a mutually exclusive branch (e.g. ReflectionFunction in `if` and ReflectionMethod in `else`) is valid PHP, but was rejected with "Cannot re-assign typed object". Route both re-assignment sites through reassignInferredObjectVar(), which widens an inferred local to a generic dynamic object. Parameters, native objects, and explicitly declared object types keep the strict check.
|
Thanks for the analysis and the patch, @Tinywan. We don't accept this direction — to be direct: TypePHP does not allow re-assigning a variable to a different type, so this PR will be closed. Rationale: TypePHP follows an AOT / static-compilation model. A variable's type is fixed from its first assignment (or explicit declaration). Assigning two unrelated concrete classes across mutually exclusive if/else branches means "one variable carrying different types", which is a type violation. Silently widening an inferred local into a generic dynamic object on those branches — as If you genuinely need a variable to hold different types across branches, declare it explicitly as $a = 'strlen';
$ref = std::any(); // dynamic object: any type/class can be assigned later
if (is_string($a)) {
$ref = new ReflectionFunction($a);
} else {
$ref = new ReflectionMethod($a, 'count');
}Declaring the intent with |
A local variable has no type declaration; its class is inferred from the first assignment. Re-assigning an unrelated concrete class in a mutually exclusive branch (e.g. ReflectionFunction in
ifand ReflectionMethod inelse) is valid PHP, but was rejected with "Cannot re-assign typed object".Route both re-assignment sites through reassignInferredObjectVar(), which widens an inferred local to a generic dynamic object. Parameters, native objects, and explicitly declared object types keep the strict check.